{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Putting it all Together"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Positionals Only: no extra positionals, no defaults (all positionals required)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(a, b):\n",
    "    print(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "func('hello', 'world')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "func(b='world', a='hello')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Positionals Only: no extra positionals, defaults (some positionals optional)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(a, b='world', c=10):\n",
    "    print(a, b, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world 10\n"
     ]
    }
   ],
   "source": [
    "func('hello')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world !\n"
     ]
    }
   ],
   "source": [
    "func('hello', c='!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Positionals Only: extra positionals, no defaults (all positionals required)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(a, b, *args):\n",
    "    print(a, b, args)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 ('x', 'y', 'z')\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, 'x', 'y', 'z')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that we cannot call the function this way:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-9-f1b0ffb3b67d>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-9-f1b0ffb3b67d>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    func(b=2, a=1, 'x', 'y', 'z')\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "func(b=2, a=1, 'x', 'y', 'z')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords Only: no positionals, no defaults (all keyword args required)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(*, a, b):\n",
    "    print(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2\n"
     ]
    }
   ],
   "source": [
    "func(a=1, b=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords Only: no positionals, some defaults (not all keyword args required)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(*, a=1, b):\n",
    "    print(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 20\n"
     ]
    }
   ],
   "source": [
    "func(a=10, b=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2\n"
     ]
    }
   ],
   "source": [
    "func(b=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: some positionals (no defaults), keywords (no defaults)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(a, b, *, c, d):\n",
    "    print(a, b, c, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, c=3, d=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, d=4, c=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, c=3, d=4, b=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: some positional defaults"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(a, b=2, *, c, d=4):\n",
    "    print(a, b, c, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, c=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(c=3, a=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, c=3, d=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4\n"
     ]
    }
   ],
   "source": [
    "func(c=3, a=1, b=2, d=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: extra positionals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(a, b=2, *args, c=3, d):\n",
    "    print(a, b, args, c, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 ('x', 'y', 'z') 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, 'x', 'y', 'z', c=3, d=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that if we are going to use the extra arguments, then we cannot actually use a default value for b:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 x ('y', 'z') 3 4\n"
     ]
    }
   ],
   "source": [
    "func(1, 'x', 'y', 'z', c=3, d=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "as you can see, **b** was assigned the value **x**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: no extra positionals, extra keywords"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(a, b, *, c, d=4, **kwargs):\n",
    "    print(a, b, c, d, kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 {'x': 100, 'y': 200, 'z': 300}\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, c=3, x=100, y=200, z=300)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 {'x': 100, 'y': 200, 'z': 300}\n"
     ]
    }
   ],
   "source": [
    "func(x=100, y=200, z=300, c=3, b=2, a=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: extra positionals, extra keywords"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(a, b, *args, c, d=4, **kwargs):\n",
    "    print(a, b, args, c, d, kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 ('x', 'y', 'z') 3 5 {'x': 100, 'y': 200, 'z': 300}\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, 'x', 'y', 'z', c=3, d=5, x=100, y=200, z=300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keywords and Positionals: only extra positionals and extra keywords"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(*args, **kwargs):\n",
    "    print(args, kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 3) {'x': 100, 'y': 200, 'z': 300}\n"
     ]
    }
   ],
   "source": [
    "func(1, 2, 3, x=100, y=200, z=300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The Print Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function print in module builtins:\n",
      "\n",
      "print(...)\n",
      "    print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n",
      "    \n",
      "    Prints the values to a stream, or to sys.stdout by default.\n",
      "    Optional keyword arguments:\n",
      "    file:  a file-like object (stream); defaults to the current sys.stdout.\n",
      "    sep:   string inserted between values, default a space.\n",
      "    end:   string appended after the last value, default a newline.\n",
      "    flush: whether to forcibly flush the stream.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(print)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3\n"
     ]
    }
   ],
   "source": [
    "print(1, 2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1--2--3\n"
     ]
    }
   ],
   "source": [
    "print(1, 2, 3, sep='--')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3***\n"
     ]
    }
   ],
   "source": [
    "print(1, 2, 3, end='***\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\t2\t3\t***\t4\t5\t6\t***\n"
     ]
    }
   ],
   "source": [
    "print(1, 2, 3, sep='\\t', end='\\t***\\t')\n",
    "print(4, 5, 6, sep='\\t', end='\\t***\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Another Use Case"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def calc_hi_lo_avg(*args, log_to_console=False):\n",
    "    hi = int(bool(args)) and max(args)\n",
    "    lo = int(bool(args)) and min(args)\n",
    "    avg = (hi + lo)/2\n",
    "    if log_to_console:\n",
    "        print(\"high={0}, low={1}, avg={2}\".format(hi, lo, avg))\n",
    "    return avg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.0\n"
     ]
    }
   ],
   "source": [
    "avg = calc_hi_lo_avg(1, 2, 3, 4, 5)\n",
    "print(avg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "high=5, low=1, avg=3.0\n",
      "3.0\n"
     ]
    }
   ],
   "source": [
    "avg = calc_hi_lo_avg(1, 2, 3, 4, 5, log_to_console=True)\n",
    "print(avg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
